package com.nuc.bigdata.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.nuc.bigdata.exception.BusinessException;
import com.nuc.bigdata.model.ResultCode;
import feign.Response;
import feign.Util;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.io.Reader;

import static feign.FeignException.errorStatus;

/**
 * feign服务异常的统一处理
 * @author JackLuo
 * @date 2019/11/1
 */
public final class FeignClientErrorDecoderCommon {

    public static Exception errorDecoder(String methodKey, Response response) {
        Reader reader = null;
        String string = null;
        JSONObject jsonObject = null;
        String exceptionMsg = null;
        if (response.status() >= 500 && response.status() <= 599) {
            try {
                // 获取读取文本流，方便转换为可读字符串
                reader = response.body().asReader();
                // 使用feign自带的util工具将输入字符流，转化为字符串
                string = Util.toString(reader);
                // 将服务端异常响应信息转化为Object对象，方便取值操作
                jsonObject = JSON.parseObject(string);
                // 在BusinessException中重写父类的getMessage方法，来将异常信息插入；这里就获取抛出的异常信息
                exceptionMsg = jsonObject.getString("message");
                JSONObject  exception = JSON.parseObject(exceptionMsg);
                if (!StringUtils.isEmpty(exception.getString(BusinessException.CLASS_MSG)) &&
                    exception.getString(BusinessException.CLASS_MSG).equals(BusinessException.CLASS_CODE)) {
                    // 将异常信息字符串转化为Object对象。方便操作
                    JSONObject object = JSON.parseObject(exceptionMsg);
                    // 获取业务异常中的code
                    Integer errorCode = object.getInteger("code");
                    String errorMsg = object.getString("msg");
                    String errorData = object.getString("error");
                    JSONObject errorDataObject = JSON.parseObject(errorData);
                    throw new BusinessException(errorCode,errorMsg ,errorDataObject );
                }else {
                    throw new BusinessException(ResultCode.WEB_ERROR,exception );
                }
            } catch (IOException e) {
                e.printStackTrace();
            } catch (JSONException e) {
                throw new BusinessException(ResultCode.WEB_ERROR,exceptionMsg );
            }
        }
        return errorStatus(methodKey, response);
    }
}
